home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 051-075 / 055 / vt100 / expand.c next >
C/C++ Source or Header  |  1995-03-13  |  9KB  |  355 lines

  1. /*************************************************************
  2.  * vt100 terminal emulator - Wild card and Directory support
  3.  *
  4.  *    v2.6 870227 DBW - bug fixes for all the stuff in v2.5
  5.  *    v2.5 870214 DBW - more additions (see readme file)
  6.  *    v2.4 861214 DBW - lots of fixes/additions (see readme file)
  7.  *    v2.3 861101 DBW - minor bug fixes
  8.  *    v2.2 861012 DBW - more of the same
  9.  *    v2.1 860915 DBW    - new features (see README)
  10.  *           860830 Steve Drew Added Wild card support,
  11.  *            features(expand.c)
  12.  *    v2.0 860809 DBW - Major rewrite
  13.  *    v1.1 860720 DBW    - Switches, 80 cols, colors, bug fixes
  14.  *    v1.0 860712 DBW    - First version released
  15.  *
  16.  *      Much of the code from this module extracted from
  17.  *      Matt Dillons Shell program. (Thanxs Matt.)
  18.  *************************************************************/
  19.  
  20. #include "vt100.h"
  21.  
  22. struct DPTR {                    /* Format of directory fetch ptr */
  23.    struct FileLock *lock;        /* lock on directory   */
  24.    struct FileInfoBlock *fib;    /* mod'd fib for entry */
  25. };
  26.  
  27. /*
  28.  * Disk directory routines
  29.  *
  30.  *
  31.  * diropen() returns a struct DPTR, or NULL if the given file does not
  32.  * exist.  stat will be set to 1 if the file is a directory.  If the
  33.  * name is "", then the current directory is openned.
  34.  *
  35.  * dirnext() returns 1 until there are no more entries.  The **name and
  36.  * *stat are set.  *stat = 1 if the file is a directory.
  37.  *
  38.  * dirclose() closes a directory channel.
  39.  *
  40.  */
  41.  
  42. struct DPTR *
  43. diropen(name, stat)
  44. char *name;
  45. int *stat;
  46. {
  47.    struct DPTR *dp;
  48.    int namelen, endslash = 0;
  49.    struct FileLock *MyLock;
  50.    
  51.    MyLock = (struct FileLock *)( (ULONG) ((struct Process *)
  52.                                  (FindTask(NULL)))->pr_CurrentDir);
  53.    namelen = strlen(name);
  54.    if (namelen && name[namelen - 1] == '/') {
  55.       name[namelen - 1] = '\0';
  56.       endslash = 1;
  57.    }
  58.    *stat = 0;
  59.    dp = (struct DPTR *)malloc(sizeof(struct DPTR));
  60.    if (*name == '\0') 
  61.       dp->lock = (struct FileLock *)DupLock (MyLock);
  62.    else
  63.       dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
  64.    if (endslash)
  65.       name[namelen - 1] = '/';
  66.    if (dp->lock == NULL) {
  67.       free (dp);
  68.       return (NULL);
  69.    }
  70.    dp->fib = (struct FileInfoBlock *)
  71.          AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
  72.    if (!Examine (dp->lock, dp->fib)) {
  73.       dirclose (dp);
  74.       return (NULL);
  75.    }
  76.    if (dp->fib->fib_DirEntryType >= 0)
  77.       *stat = 1;
  78.    return (dp);
  79. }
  80.  
  81. dirnext(dp, pname, stat)
  82. struct DPTR *dp;
  83. char **pname;
  84. int *stat;
  85. {
  86.    if (dp == NULL)
  87.       return (0);
  88.    if (ExNext (dp->lock, dp->fib)) {
  89.       *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
  90.       *pname = dp->fib->fib_FileName;
  91.       return (1);
  92.    }
  93.    return (0);
  94. }
  95.  
  96.  
  97. dirclose(dp)
  98. struct DPTR *dp;
  99. {
  100.    if (dp == NULL)
  101.       return (1);
  102.    if (dp->fib)
  103.       FreeMem (dp->fib, (long)sizeof(*dp->fib));
  104.    if (dp->lock)
  105.       UnLock (dp->lock);
  106.    free (dp);
  107.    return (1);
  108. }
  109.  
  110. free_expand(av)
  111. char **av;
  112. {
  113.    char **base = av;
  114.  
  115.    if (av) {
  116.       while (*av) {
  117.          free (*av);
  118.          ++av;
  119.       }
  120.       free (base);
  121.    }
  122. }
  123.  
  124. /*
  125.  * EXPAND(wild_name, pac)
  126.  *    wild_name      - char * (example: "df0:*.c")
  127.  *    pac            - int  *  will be set to # of arguments.
  128.  *
  129.  */
  130.  
  131.  
  132. char **
  133. expand(base, pac)
  134. char *base;
  135. int *pac;
  136. {
  137.    char **eav = (char **)malloc (sizeof(char *));
  138.    int  eleft, eac;
  139.  
  140.    char *ptr, *name;
  141.    char *bname, *ename, *tail;
  142.    int stat, scr;
  143.    struct DPTR *dp;
  144.  
  145.    *pac = eleft = eac = 0;
  146.    base = strcpy(malloc(strlen(base)+1), base);
  147.    for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
  148.    for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
  149.    if (ptr < base) {
  150.       bname = strcpy (malloc(1), "");
  151.    } else {
  152.       scr = ptr[1];
  153.       ptr[1] = '\0';
  154.       bname = strcpy (malloc(strlen(base)+1), base);
  155.       ptr[1] = scr;
  156.    }
  157.    ename = ptr + 1;
  158.    for (ptr = ename; *ptr && *ptr != '/'; ++ptr);
  159.    scr = *ptr;
  160.    *ptr = '\0';
  161.    tail = (scr) ? ptr + 1 : NULL;
  162.  
  163.    if ((dp = diropen (bname, &stat)) == NULL  ||  stat == 0) {
  164.       free (bname);
  165.       free (base);
  166.       free (eav);
  167.       req ("Could not open directory","",0);
  168.       return (NULL);
  169.    }
  170.    while (dirnext (dp, &name, &stat)) {
  171.       if (compare_ok(ename, name)) {
  172.          if (tail) {
  173.             int alt_ac;
  174.             char *search, **alt_av, **scrav;
  175.             struct FileLock *lock;
  176.  
  177.             if (!stat)      /* expect more dirs, but this not a dir */
  178.                continue;
  179.             lock = (struct FileLock *)CurrentDir (dp->lock);
  180.             search = malloc(strlen(name)+strlen(tail)+2);
  181.             strcpy (search, name);
  182.             strcat (search, "/");
  183.             strcat (search, tail);
  184.             scrav = alt_av = expand (search, &alt_ac);
  185.             CurrentDir (lock);
  186.             if (scrav) {
  187.                while (*scrav) {
  188.                   if (eleft < 2) {
  189.                      char **scrav = (char **)
  190.             malloc(sizeof(char *) * (eac + 10));
  191.                      movmem (eav, scrav, sizeof(char *) * (eac + 1));
  192.                      free (eav);
  193.                      eav = scrav;
  194.                      eleft = 10;
  195.                   }
  196.                   eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1);
  197.                   strcpy(eav[eac], bname);
  198.                   strcat(eav[eac], *scrav);
  199.                   free (*scrav);
  200.                   ++scrav;
  201.                   --eleft, ++eac;
  202.                }
  203.                free (alt_av);
  204.             }
  205.          } else {
  206.             if (eleft < 2) {
  207.                char **scrav = (char **)
  208.             malloc(sizeof(char *) * (eac + 10));
  209.                movmem (eav, scrav, sizeof(char *) * (eac + 1));
  210.                free (eav);
  211.                eav = scrav;
  212.                eleft = 10;
  213.             }
  214.             eav[eac] = malloc (strlen(bname)+strlen(name)+1);
  215.             eav[eac] = strcpy(eav[eac], bname);
  216.             strcat(eav[eac], name);
  217.             --eleft, ++eac;
  218.          }
  219.       }
  220.    }
  221.    dirclose (dp);
  222.    *pac = eac;
  223.    eav[eac] = NULL;
  224.    free (bname);
  225.    free (base);
  226.    if (eac)
  227.       return (eav);
  228.    free (eav);
  229.    return (NULL);
  230. }
  231.  
  232. /*
  233.  * Compare a wild card name with a normal name
  234.  */
  235.  
  236. #define MAXB   8
  237.  
  238. compare_ok(wild, name)
  239. char *wild, *name;
  240. {
  241.    char *w = wild;
  242.    char *n = name;
  243.    char *back[MAXB][2];
  244.    int  bi = 0;
  245.  
  246.    while (*n || *w) {
  247.       switch (*w) {
  248.       case '*':
  249.          if (bi == MAXB) {
  250.             req ("Too many levels of '*'","",0);
  251.             return (0);
  252.          }
  253.          back[bi][0] = w;
  254.          back[bi][1] = n;
  255.          ++bi;
  256.          ++w;
  257.          continue;
  258. goback:
  259.          --bi;
  260.          while (bi >= 0 && *back[bi][1] == '\0')
  261.             --bi;
  262.          if (bi < 0)
  263.             return (0);
  264.          w = back[bi][0] + 1;
  265.          n = ++back[bi][1];
  266.          ++bi;
  267.          continue;
  268.       case '?':
  269.          if (!*n) {
  270.             if (bi)
  271.                goto goback;
  272.             return (0);
  273.          }
  274.          break;
  275.       default:
  276.          if (toupper(*n) != toupper(*w)) {
  277.             if (bi)
  278.                goto goback;
  279.             return (0);
  280.          }
  281.          break;
  282.       }
  283.       if (*n)  ++n;
  284.       if (*w)  ++w;
  285.    }
  286.    return (1);
  287. }
  288.  
  289. set_dir(new)
  290. char *new;
  291. {
  292.    register     char         *s;
  293.    int               i;
  294.    struct     FileLock     *lock;
  295.    char             temp[60];
  296.    struct       FileInfoBlock   *fib;
  297.   
  298.    if (*new != '\000') {
  299.       strcpy(temp, MyDir);
  300.       s = new;
  301.       if (*s == '/') {
  302.          s++;
  303.          for (i=strlen(MyDir);
  304.               MyDir[i] != '/' && MyDir[i] != ':';
  305.               i--);
  306.          MyDir[i+1] = '\0';
  307.          strcat(MyDir, s);
  308.          }
  309.       else if (exists(s, ':') == 0) {
  310.          if (MyDir[strlen(MyDir)-1] != ':')
  311.             strcat(MyDir, "/");
  312.          strcat(MyDir, s);
  313.          }
  314.       else
  315.          strcpy(MyDir, s);
  316.  
  317.       if ((lock = (struct FileLock *)Lock(MyDir, (long)ACCESS_READ)) == 0) {
  318.          req("Directory not found:",MyDir,0);
  319.          strcpy(MyDir, temp);
  320.          }
  321.       else {
  322.      fib = (struct FileInfoBlock *)AllocMem(
  323.         (long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
  324.      if (fib) {
  325.               if (Examine(lock, fib)) {
  326.               if (fib->fib_DirEntryType > 0) {
  327.             CurrentDir(lock);
  328.             if (MyDirLock != NULL) UnLock(MyDirLock);
  329.             MyDirLock = lock;
  330.             if (MyDir[strlen(MyDir)-1] == '/')
  331.             MyDir[strlen(MyDir)-1] = '\000';
  332.             }
  333.         else {
  334.                     req("Not a Directory:",MyDir,0);               
  335.                     strcpy(MyDir,temp);
  336.             }
  337.         }
  338.         FreeMem(fib, (long)sizeof(struct FileInfoBlock));
  339.         }
  340.     else {
  341.         req("Can't change directory... ","No free memory!",0);
  342.         strcpy(MyDir,temp);
  343.         }
  344.     }
  345.     }
  346. }
  347.  
  348. exists(s,c)
  349. char *s,c;
  350.     {
  351.     while (*s != '\000')
  352.     if (*s++ == c) return(1);
  353.     return(0);
  354.     }
  355.